/*
 * Copyright (c) Huawei Device Co., Ltd. 2024. All rights reserved.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "ef_odf.h"

#include <unistd.h>

#include "common_utils.h"
#include "der_parser.h"
#include "loghelper.h"

namespace OHOS {
namespace SE {
EfOdf::EfOdf() : EfParser()
{
}

EfOdf::~EfOdf()
{
}

std::vector<uint8_t> EfOdf::ParseOdfFileData(const std::vector<uint8_t> &fileData)
{
    std::shared_ptr<DerParser> der = std::make_shared<DerParser>(fileData);
    std::vector<uint8_t> dodfPath;
    while (!der->IsParsingEnd()) {
        if (der->GetTlvType() == TAG_DODF_PATH) {
            dodfPath = der->ParseEfPath();
        } else {
            der->SkipTlvData();
        }
    }
    return dodfPath;
}

std::vector<uint8_t> EfOdf::ReadOdfFileByPath(const std::vector<uint8_t> &odfFilePath)
{
    InfoLog("Parsing ODF file by path, filesize = %{public}lu", odfFilePath.size());
    std::vector<uint8_t> path;
    if (odfFilePath.size() != 0) {
        path.insert(path.end(), odfFilePath.begin(), odfFilePath.end());
        path.insert(path.end(), ODF_DEFAULT_PATH.begin(), ODF_DEFAULT_PATH.end());
    } else {
        path = ODF_DEFAULT_PATH;
    }

    uint16_t rspApdu = 0;
    if (!ReadFileByPath(path, rspApdu)) {
        sleep(1);
        WarnLog("fail to read odf path, rspApdu[%{public}x], retrying...", rspApdu);
        if (!ReadFileByPath(path, rspApdu)) {
            ErrorLog("fail to read odf path, rspApdu[%{public}x]", rspApdu);
            return std::vector<uint8_t>();
        }
    }
    std::vector<uint8_t> odfFileData = ReadFileByDataSize(0, -1);
    return ParseOdfFileData(odfFileData);
}
}  // namespace SE
}  // namespace OHOS
